import requests
import random
import time
import json
import os
import sys
import threading
from queue import Queue

# cron: 15 21 * * *
# new Env("牛牛免费短剧")
# 从环境变量读取配置
# 抓包https://new.tianjinzhitongdaohe.com/api/v1/app内的token1#deviceId1#name1填入NNDJ_CONFIGS变量内多变量用换行
NNDJ_CONFIGS = os.getenv('NNDJ_CONFIGS', '').strip()
NNDJ_PROXY = os.getenv('NNDJ_PROXY', '').strip()
NNDJ_THREAD = int(os.getenv('NNDJ_THREAD', '1'))  # 线程数，默认1
# 延迟控制环境变量
MIN_USER_DELAY = int(os.getenv('NNDJ_MIN_USER_DELAY', '3'))  # 用户间最小延迟，默认3秒
MAX_USER_DELAY = int(os.getenv('NNDJ_MAX_USER_DELAY', '10'))  # 用户间最大延迟，默认10秒
MIN_TASK_DELAY = int(os.getenv('NNDJ_MIN_TASK_DELAY', '1'))  # 任务间最小延迟，默认1秒
MAX_TASK_DELAY = int(os.getenv('NNDJ_MAX_TASK_DELAY', '5'))  # 任务间最大延迟，默认5秒

# 解析用户配置
USERS = []
if NNDJ_CONFIGS:
    user_lines = [line.strip() for line in NNDJ_CONFIGS.split('\n') if line.strip()]
    for idx, line in enumerate(user_lines, 1):
        parts = line.split('#')
        if len(parts) >= 2:
            user = {
                "token": parts[0].strip(),
                "deviceId": parts[1].strip(),
                "name": parts[2].strip() if len(parts) > 2 else f"账号{idx}",
                "index": idx  # 添加用户序号
            }
            USERS.append(user)
    print(f"成功加载 {len(USERS)} 个用户配置")
else:
    print("错误：未设置 NNDJ_CONFIGS 环境变量！")
    print("请按以下格式设置环境变量：")
    print("export NNDJ_CONFIGS=\"token1#deviceId1#name1\\ntoken2#deviceId2#name2\"")
    sys.exit(1)

# 基础配置
BASE_URL = 'https://new.tianjinzhitongdaohe.com/api/v1/app'
COMMON_DATA = {"pageSize": "15"}

def wait_for_proxy():
    """等待直到获取有效代理"""
    global NNDJ_PROXY
    
    if not NNDJ_PROXY:
        print("错误：未设置 NNDJ_PROXY 环境变量！")
        print("请设置代理环境变量，例如：")
        print("export NNDJ_PROXY=\"http://127.0.0.1:8888\"")
        while not NNDJ_PROXY:
            print("等待代理配置...60秒后重试")
            time.sleep(60)
            NNDJ_PROXY = os.getenv('NNDJ_PROXY', '').strip()
    print(f"使用代理: {NNDJ_PROXY}")

def random_delay(min_seconds, max_seconds):
    """生成随机延迟时间"""
    delay = random.uniform(min_seconds, max_seconds)
    time.sleep(delay)
    return delay

class UserSession:
    """用户会话类，封装单个用户的所有操作"""
    def __init__(self, user_config):
        self.name = user_config["name"]
        self.token = user_config["token"]
        self.deviceId = user_config["deviceId"]
        self.user_index = user_config["index"]  # 用户序号
        self.headers = self._create_headers()
        self.proxies = self._create_proxies()
        self.last_treasure_time = 0
        self.account_name = None  # 账号昵称
        self.pre_gold = 0         # 运行前金币
        self.pre_balance = 0.0     # 运行前余额
        self.post_gold = 0        # 运行后金币
        self.post_balance = 0.0    # 运行后余额
        
    def _create_headers(self):
        """创建用户特定的请求头"""
        return {
            'User-Agent': 'niu niu duan ju/1.5.8 (iPhone; iOS 16.6; Scale/3.00)',
            'Content-Type': 'application/json',
            'deviceType': 'iOS',
            'Accept-Language': 'zh-Hans-CN;q=1',
            'token': self.token,
            'deviceId': self.deviceId,
            'client': 'app',
            'Cookie': 'JSESSIONID=767F1CFB5FB471A4F2871314C74F14B6'
        }
    
    def _create_proxies(self):
        """创建代理设置"""
        if NNDJ_PROXY:
            return {
                'http': NNDJ_PROXY,
                'https': NNDJ_PROXY
            }
        return None
    
    def make_request(self, url, data=None, method='POST', params=None):
        """通用请求函数"""
        try:
            kwargs = {
                'headers': self.headers,
                'json': data if method == 'POST' else None,
                'params': params,
                'proxies': self.proxies,
                'timeout': 30
            }
            
            if method == 'POST':
                response = requests.post(url, **kwargs)
            else:
                response = requests.get(url, **kwargs)
            
            if response.status_code == 200:
                return response.json()
            else:
                print(f"[用户{self.user_index} {self.name}] 请求失败，状态码: {response.status_code}")
                return None
        except Exception as e:
            print(f"[用户{self.user_index} {self.name}] 请求异常: {str(e)}")
            return None
    
    def get_user_info(self):
        """获取用户信息（账号名、金币、余额）"""
        url = f'{BASE_URL}/user/userInfo'
        result = self.make_request(url, method='GET')
        
        if result and result.get('code') == 200:
            data = result.get('data', {})
            self.account_name = data.get('nickName', '未知')
            self.pre_gold = data.get('goldBalance', 0)
            self.pre_balance = data.get('balance', 0.0)
            return True
        return False
    
    def update_user_info(self):
        """更新用户信息（运行后调用）"""
        url = f'{BASE_URL}/user/userInfo'
        result = self.make_request(url, method='GET')
        
        if result and result.get('code') == 200:
            data = result.get('data', {})
            self.post_gold = data.get('goldBalance', 0)
            self.post_balance = data.get('balance', 0.0)
            return True
        return False
    
    def sign_in(self):
        """每日签到"""
        url = f'{BASE_URL}/welfare/sign'
        return self.make_request(url, data=COMMON_DATA)
    
    def check_repair_sign(self):
        """检查补签需求"""
        url = f'{BASE_URL}/welfare/list'
        return self.make_request(url, data=COMMON_DATA)
    
    def repair_sign(self, config_id):
        """执行补签"""
        time.sleep(5)
        url = f'{BASE_URL}/welfare/repairSign?configId={config_id}'
        return self.make_request(url, data=COMMON_DATA)
    
    def watch_ad(self, times=20, interval=5):
        """看视频领金币"""
        results = []
        data = {
            "adId": "58274289-127E-48FF-910F-9B96118908F3u2283",
            "pageSize": "15"
        }
        
        for i in range(times):
            url = f'{BASE_URL}/welfare/watchAd'
            result = self.make_request(url, data=data)
            results.append(result)
            
            if i < times - 1:
                # 在视频之间添加随机延迟
                delay = random_delay(interval, interval + 2)
                print(f"[用户{self.user_index} {self.name}] 视频任务间随机延迟: {delay:.2f}秒")
        
        return results
    
    def watch_drama(self):
        """看短剧领金币"""
        url = f'{BASE_URL}/play/historyMovie'
        data = {
            "id": 77834,
            "typeId": "S1",
            "watchDuration": 3600,
            "pageSize": "15",
            "episode": ""
        }
        return self.make_request(url, data=data)
    
    def sign_eat(self):
        """吃饭看剧补贴"""
        url = f'{BASE_URL}/welfare/signEat'
        return self.make_request(url, data=COMMON_DATA)
    
    def repair_sign_eat(self, config_id):
        """吃饭看剧补领"""
        time.sleep(5)
        url = f'{BASE_URL}/welfare/repairSignEat?configId={config_id}'
        return self.make_request(url, data=COMMON_DATA)
    
    def open_treasure(self):
        """开宝箱（只执行一次）"""
        url = f'{BASE_URL}/welfare/treasureOpen'
        return self.make_request(url, data=COMMON_DATA)
    
    def new_user_seven(self):
        """新用户奖励"""
        url = f'{BASE_URL}/welfare/newUserSeven'
        return self.make_request(url, data=COMMON_DATA)
    
    def praise_movie(self, times=2):
        """点赞剧集"""
        results = []
        for _ in range(times):
            url = f'{BASE_URL}/play/praiseMovie'
            data = {
                "movieId": random.randint(1, 70000),
                "typeId": "S1",
                "episodeIndex": 0,
                "source": 0,
                "pageSize": "15",
                "action": "1"
            }
            results.append(self.make_request(url, data=data))
            # 点赞之间添加随机延迟
            delay = random_delay(1, 3)
            print(f"[用户{self.user_index} {self.name}] 点赞任务间随机延迟: {delay:.2f}秒")
        return results
    
    def collect_movie(self, times=2):
        """收藏剧集"""
        results = []
        for _ in range(times):
            url = f'{BASE_URL}/play/collectMovie'
            data = {
                "id": random.randint(1, 70000),
                "typeId": "S1",
                "pageSize": "15",
                "action": "1"
            }
            results.append(self.make_request(url, data=data))
            # 收藏之间添加随机延迟
            delay = random_delay(1, 3)
            print(f"[用户{self.user_index} {self.name}] 收藏任务间随机延迟: {delay:.2f}秒")
        return results
    
    def share_movie(self, times=2):
        """分享剧集"""
        results = []
        for _ in range(times):
            # 分享之间添加随机延迟
            delay = random_delay(2, 5)
            print(f"[用户{self.user_index} {self.name}] 分享任务前随机延迟: {delay:.2f}秒")
            
            movie_id = random.randint(1, 70000)
            url = f'{BASE_URL}/welfare/addShare?typeId=S1&movieId={movie_id}'
            results.append(self.make_request(url, data=COMMON_DATA))
        return results
    
    def process_sign_repair(self, check_result):
        """处理签到补签逻辑"""
        if not check_result or 'data' not in check_result:
            print(f"[用户{self.user_index} {self.name}] 未获取到有效的补签检查结果")
            return
        
        sign_task = next((task for task in check_result['data'] if task.get('flag') == 'SIGN'), None)
        
        if sign_task and 'taskList' in sign_task:
            for task_item in sign_task['taskList']:
                if task_item.get('isDone') is False:
                    config_id = task_item.get('configId')
                    if config_id:
                        print(f"[用户{self.user_index} {self.name}] 发现需要补签的任务: {task_item.get('number')}天")
                        repair_result = self.repair_sign(config_id)
                        if repair_result and repair_result.get('code') == 200:
                            print(f"[用户{self.user_index} {self.name}] 补签成功 (configId={config_id}): {repair_result.get('msg')}")
                        else:
                            print(f"[用户{self.user_index} {self.name}] 补签失败 (configId={config_id}): {repair_result.get('msg') if repair_result else '未知错误'}")
    
    def process_eat_repair(self, check_result):
        """处理吃饭看剧补贴补领逻辑"""
        if not check_result or 'data' not in check_result:
            print(f"[用户{self.user_index} {self.name}] 未获取到有效的补签检查结果")
            return
        
        eat_task = next((task for task in check_result['data'] if task.get('flag') == 'WATCH_EAT_COIN'), None)
        
        if eat_task and 'taskList' in eat_task:
            for task_item in eat_task['taskList']:
                if task_item.get('isDone') is False and task_item.get('isReceive') is False:
                    config_id = task_item.get('configId')
                    if config_id:
                        print(f"[用户{self.user_index} {self.name}] 发现需要补领的吃饭看剧补贴任务: 时段{task_item.get('number')}")
                        repair_result = self.repair_sign_eat(config_id)
                        if repair_result and repair_result.get('code') == 200:
                            print(f"[用户{self.user_index} {self.name}] 吃饭补贴补领成功 (configId={config_id}): {repair_result.get('msg')}")
                        else:
                            print(f"[用户{self.user_index} {self.name}] 吃饭补贴补领失败 (configId={config_id}): {repair_result.get('msg') if repair_result else '未知错误'}")

    def auto_sign(self):
        """自动签到完整流程"""
        print(f"[用户{self.user_index} {self.name}] {'='*50}")
        print(f"[用户{self.user_index} {self.name}] 开始执行自动签到任务")
        
        # 获取运行前用户信息
        if self.get_user_info():
            print(f"[用户{self.user_index} {self.name}] 账号昵称: {self.account_name}")
            print(f"[用户{self.user_index} {self.name}] 当前金币: {self.pre_gold}，余额: ¥{self.pre_balance:.2f}")
        else:
            print(f"[用户{self.user_index} {self.name}] 获取用户信息失败，跳过统计")
        
        print(f"[用户{self.user_index} {self.name}] {'='*50}")
        
        # 1. 执行签到
        print(f"[用户{self.user_index} {self.name}] >>> 执行每日签到")
        sign_result = self.sign_in()
        if sign_result and sign_result.get('code') == 200:
            print(f"[用户{self.user_index} {self.name}] 签到成功: {sign_result.get('msg')}")
        else:
            print(f"[用户{self.user_index} {self.name}] 签到失败: {sign_result.get('msg') if sign_result else '请求失败'}")
        
        # 任务间随机延迟
        delay = random_delay(MIN_TASK_DELAY, MAX_TASK_DELAY)
        print(f"[用户{self.user_index} {self.name}] 任务间随机延迟: {delay:.2f}秒")
        
        # 2. 检查补签需求
        print(f"[用户{self.user_index} {self.name}] >>> 检查补签需求")
        check_result = self.check_repair_sign()
        
        # 任务间随机延迟
        delay = random_delay(MIN_TASK_DELAY, MAX_TASK_DELAY)
        print(f"[用户{self.user_index} {self.name}] 任务间随机延迟: {delay:.2f}秒")
        
        # 3. 处理补签
        if check_result and check_result.get('code') == 200:
            print(f"[用户{self.user_index} {self.name}] 补签检查结果获取成功")
            self.process_sign_repair(check_result)
            self.process_eat_repair(check_result)
        else:
            print(f"[用户{self.user_index} {self.name}] 补签检查失败: {check_result.get('msg') if check_result else '请求失败'}")
        
        # 任务间随机延迟
        delay = random_delay(MIN_TASK_DELAY, MAX_TASK_DELAY)
        print(f"[用户{self.user_index} {self.name}] 任务间随机延迟: {delay:.2f}秒")
        
        # 4. 看视频领金币
        print(f"[用户{self.user_index} {self.name}] >>> 开始看视频领金币 (20次)")
        ad_results = self.watch_ad(times=20, interval=5)
        success_count = sum(1 for r in ad_results if r and r.get('code') == 200)
        print(f"[用户{self.user_index} {self.name}] 看视频完成: 成功 {success_count}/20 次")
        
        # 任务间随机延迟
        delay = random_delay(MIN_TASK_DELAY, MAX_TASK_DELAY)
        print(f"[用户{self.user_index} {self.name}] 任务间随机延迟: {delay:.2f}秒")
        
        # 5. 看短剧
        print(f"[用户{self.user_index} {self.name}] >>> 看短剧领金币")
        drama_result = self.watch_drama()
        if drama_result and drama_result.get('code') == 200:
            print(f"[用户{self.user_index} {self.name}] 看短剧成功: {drama_result.get('msg')}")
        else:
            print(f"[用户{self.user_index} {self.name}] 看短剧失败: {drama_result.get('msg') if drama_result else '请求失败'}")
        
        # 任务间随机延迟
        delay = random_delay(MIN_TASK_DELAY, MAX_TASK_DELAY)
        print(f"[用户{self.user_index} {self.name}] 任务间随机延迟: {delay:.2f}秒")
        
        # 6. 吃饭补贴
        print(f"[用户{self.user_index} {self.name}] >>> 吃饭看剧补贴")
        eat_result = self.sign_eat()
        if eat_result and eat_result.get('code') == 200:
            print(f"[用户{self.user_index} {self.name}] 吃饭补贴成功: {eat_result.get('msg')}")
        else:
            print(f"[用户{self.user_index} {self.name}] 吃饭补贴失败: {eat_result.get('msg') if eat_result else '请求失败'}")
        
        # 任务间随机延迟
        delay = random_delay(MIN_TASK_DELAY, MAX_TASK_DELAY)
        print(f"[用户{self.user_index} {self.name}] 任务间随机延迟: {delay:.2f}秒")
        
        # 7. 开宝箱
        print(f"[用户{self.user_index} {self.name}] >>> 开启宝箱")
        treasure_result = self.open_treasure()
        if treasure_result and treasure_result.get('code') == 200:
            print(f"[用户{self.user_index} {self.name}] 宝箱开启成功: {treasure_result.get('msg')}")
        else:
            print(f"[用户{self.user_index} {self.name}] 宝箱开启失败: {treasure_result.get('msg') if treasure_result else '请求失败'}")
        
        # 任务间随机延迟
        delay = random_delay(MIN_TASK_DELAY, MAX_TASK_DELAY)
        print(f"[用户{self.user_index} {self.name}] 任务间随机延迟: {delay:.2f}秒")
        
        # 8. 新用户奖励
        print(f"[用户{self.user_index} {self.name}] >>> 新用户奖励")
        new_user_result = self.new_user_seven()
        if new_user_result and new_user_result.get('code') == 200:
            print(f"[用户{self.user_index} {self.name}] 新用户奖励成功: {new_user_result.get('msg')}")
        else:
            print(f"[用户{self.user_index} {self.name}] 新用户奖励失败: {new_user_result.get('msg') if new_user_result else '请求失败'}")
        
        # 任务间随机延迟
        delay = random_delay(MIN_TASK_DELAY, MAX_TASK_DELAY)
        print(f"[用户{self.user_index} {self.name}] 任务间随机延迟: {delay:.2f}秒")
        
        # 9. 点赞
        print(f"[用户{self.user_index} {self.name}] >>> 点赞剧集 (2次)")
        praise_results = self.praise_movie(times=2)
        success_count = sum(1 for r in praise_results if r and r.get('code') == 200)
        print(f"[用户{self.user_index} {self.name}] 点赞完成: 成功 {success_count}/2 次")
        
        # 任务间随机延迟
        delay = random_delay(MIN_TASK_DELAY, MAX_TASK_DELAY)
        print(f"[用户{self.user_index} {self.name}] 任务间随机延迟: {delay:.2f}秒")
        
        # 10. 收藏
        print(f"[用户{self.user_index} {self.name}] >>> 收藏剧集 (2次)")
        collect_results = self.collect_movie(times=2)
        success_count = sum(1 for r in collect_results if r and r.get('code') == 200)
        print(f"[用户{self.user_index} {self.name}] 收藏完成: 成功 {success_count}/2 次")
        
        # 任务间随机延迟
        delay = random_delay(MIN_TASK_DELAY, MAX_TASK_DELAY)
        print(f"[用户{self.user_index} {self.name}] 任务间随机延迟: {delay:.2f}秒")
        
        # 11. 分享
        print(f"[用户{self.user_index} {self.name}] >>> 分享剧集 (2次)")
        share_results = self.share_movie(times=2)
        success_count = sum(1 for r in share_results if r and r.get('code') == 200)
        print(f"[用户{self.user_index} {self.name}] 分享完成: 成功 {success_count}/2 次")
        
        # 获取运行后用户信息
        if self.update_user_info():
            gold_diff = self.post_gold - self.pre_gold
            balance_diff = self.post_balance - self.pre_balance
            
            print(f"\n[用户{self.user_index} {self.name}] " + "="*50)
            print(f"[用户{self.user_index} {self.name}] 任务完成统计:")
            print(f"[用户{self.user_index} {self.name}] 账号昵称: {self.account_name}")
            print(f"[用户{self.user_index} {self.name}] 金币变化: {self.pre_gold} → {self.post_gold} ({'+' if gold_diff >= 0 else ''}{gold_diff})")
            print(f"[用户{self.user_index} {self.name}] 余额变化: ¥{self.pre_balance:.2f} → ¥{self.post_balance:.2f} ({'+' if balance_diff >= 0 else ''}{balance_diff:.2f})")
            print(f"[用户{self.user_index} {self.name}] " + "="*50)
        else:
            print(f"\n[用户{self.user_index} {self.name}] " + "="*50)
            print(f"[用户{self.user_index} {self.name}] 自动签到任务执行完毕")
            print(f"[用户{self.user_index} {self.name}] " + "="*50)

def worker(user_queue):
    """工作线程函数"""
    while not user_queue.empty():
        user_config = user_queue.get()
        try:
            # 添加用户开始运行的提示
            print(f"\n{'='*60}")
            print(f"用户{user_config['index']} {user_config['name']} 开始运行")
            print(f"开始时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
            print(f"{'='*60}")
            
            user = UserSession(user_config)
            user.auto_sign()
        except Exception as e:
            print(f"处理用户 {user_config['name']} 时发生异常: {str(e)}")
        finally:
            user_queue.task_done()
            # 用户间随机延迟
            if not user_queue.empty():
                delay = random_delay(MIN_USER_DELAY, MAX_USER_DELAY)
                print(f"\n用户间随机延迟: {delay:.2f}秒")
                time.sleep(delay)

def main():
    """主函数"""
    print("=" * 60)
    print("牛牛短剧自动签到脚本")
    print(f"开始执行时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
    print(f"线程数: {NNDJ_THREAD}")
    print(f"用户间延迟范围: {MIN_USER_DELAY}-{MAX_USER_DELAY}秒")
    print(f"任务间延迟范围: {MIN_TASK_DELAY}-{MAX_TASK_DELAY}秒")
    print("=" * 60)
    
    # 等待代理可用
    wait_for_proxy()
    
    # 创建用户队列
    user_queue = Queue()
    for user in USERS:
        user_queue.put(user)
    
    # 创建并启动工作线程
    threads = []
    for i in range(NNDJ_THREAD):
        thread = threading.Thread(target=worker, args=(user_queue,))
        thread.daemon = True
        thread.start()
        threads.append(thread)
    
    # 等待所有任务完成
    user_queue.join()
    
    print("\n所有用户任务处理完成！")
    print(f"完成时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")

if __name__ == "__main__":
    main()